﻿using Net;
using Net.Share;
using Net.Server;
using Net.SceneUtility;
using ActorSystem;

namespace Example2
{
    /// <summary>
    /// 场景管理器, 状态同步, 帧同步 固定帧发送当前场景的所有玩家操作
    /// </summary>
    public class Scene : SceneBase<Client>
    {
        internal MapData mapData = new();
        internal ActorSystem.Scene scene = new();

        public void Init()
        {
            var ad = mapData.aoiData;
            scene.AOI.Init(ad.xPos, ad.zPos, ad.xMax, ad.zMax, ad.width, ad.height);
            scene.Navmesh.Init(mapData.navmeshData);
            foreach (var item in mapData.monsterPoints)
            {
                if (item.monsters == null)
                    continue;
                var patrolPath = item.patrolPath;
                for (int i = 0; i < item.monsters.Length; i++)
                {
                    var position = patrolPath.waypoints[0];
                    var monster = new AIMonster();
                    monster.Agent = scene.Navmesh.CreateAgent(monster.transform); // new AgentEntity(navmeshSystem) { agentHeight = -0.5f, findPathMode = FindPathMode.FindPathFollow };
                    monster.transform.SetPositionAndRotation(position, Quaternion.identity);
                    monster.Position = position;
                    monster.pointCenter = position;
                    //monster.health = item.monsters[i].health;
                    monster.Property = new NormalProperty();
                    scene.AddActor(monster);
                }
            }
        }

        public override void OnEnter(Client client)
        {
            var player = new Player()
            {
                Identity = client.UserId,
                MainRole = true,
                scene = this,
                client = client,
                Property = new NormalProperty(),
            };
            player.transform.Position = new Vector3(RandomHelper.Range(-20, 20), 0, RandomHelper.Range(-20, 20));
            scene.AddActor(player);
        }

        public override void OnExit(Client client)
        {
            if (Count <= 0) //如果没人时要清除操作数据，不然下次进来会直接发送Command.OnPlayerExit指令给客户端，导致客户端的对象被销毁
                operations.Clear();
            else
                AddOperation(new Operation(Command.OnPlayerExit, client.UserId));
            scene.RemoveActor(client.UserId);
        }

        /// <summary>
        /// 网络帧同步, 状态同步更新
        /// </summary>
        public override void Update()
        {
            if (Clients.Count <= 0)
                return;
            scene.Update();
            SendOperitions(operations); //不管aoi, 整个场景的同步在这里, 如玩家退出操作
            Frame++;
        }

        public override void OnOperationSync(Client client, in OperationList list)
        {
            scene.Dispatch(list);
        }
    }
}